package com.lgmshare.component.widget.recyclerview;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.List;

/**
 * Recycler Adapter基类
 *
 * @author lim
 * @description: TODO
 * @email lgmshare@gmail.com
 * @datetime 2016/5/19 18:07
 */
public abstract class RecyclerViewHFViewAdapter<T> extends RecyclerViewAdapter<T> {

    protected static final int VIEW_TYPE_HEADER = 0x00111;
    protected static final int VIEW_TYPE_FOOTER = 0x00112;

    private LinearLayout mHeaderViewContainer;
    private LinearLayout mFooterViewContainer;
    /*TODO 外部Header View的个数（如：XRecyclerView），在使用notifyItemRemoved方法时需要用到*/
    private int mExternalHeaderViewsCount;

    public RecyclerViewHFViewAdapter(Context context) {
        super(context);
    }

    /**
     * Same as RecyclerViewAdapter(Context,int) but with
     * some initialization data.
     *
     * @param context The context.
     * @param data    A new list is created out of this one to avoid mutable list
     */
    public RecyclerViewHFViewAdapter(Context context, List<T> data) {
        super(context, data);
    }

    /**
     * Add a header view
     * TODO 此方法必须在setAdapter之前调用
     *
     * @param header
     */
    public void addHeaderView(View header) {
        if (header == null) {
            throw new RuntimeException("header is null");
        }
        ensureHeaderViewContainer();
        this.mHeaderViewContainer.addView(header);
        this.notifyDataSetChanged();
    }

    /**
     * Add a footer view
     * TODO 此方法必须在setAdapter之前调用
     *
     * @param footer
     */
    public void addFooterView(View footer) {
        if (footer == null) {
            throw new RuntimeException("footer is null");
        }
        ensureFooterViewContainer();
        this.mFooterViewContainer.addView(footer);
        this.notifyDataSetChanged();
    }

    /**
     * 设置外部header的个数，特为{XRecyclerViews.class}使用
     * 实现{@link #addItem(Object)}、{@link #addList(List)}
     * {@link #removeItem(int)} {@link #removeItem(Object)} {@link #setList(List)}中的刷新功能
     * TODO 用于XRecyclerViews时必须实现此方法。
     *
     * @param externalHeaderViewsCount
     */
    public void setExternalHeaderViewsCount(int externalHeaderViewsCount) {
        mExternalHeaderViewsCount = externalHeaderViewsCount;
    }

    private void ensureHeaderViewContainer() {
        if (mHeaderViewContainer == null) {
            mHeaderViewContainer = new LinearLayout(mContext);
            mHeaderViewContainer.setOrientation(LinearLayout.VERTICAL);
            mHeaderViewContainer.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
    }

    private void ensureFooterViewContainer() {
        if (mFooterViewContainer == null) {
            mFooterViewContainer = new LinearLayout(mContext);
            mFooterViewContainer.setOrientation(LinearLayout.VERTICAL);
            mFooterViewContainer.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
    }

    ////////////////change data/////////////

    /**
     * 方法内已实现notify更新
     *
     * @param item
     */
    public void addItem(T item) {
        if (item != null) {
            this.mDataList.add(item);
        }
        this.notifyItemInserted(mDataList.size() + getHeaderViewsCount());
    }

    /**
     * 方法内已实现notify更新
     *
     * @param position
     * @param item
     */
    public void addItem(int position, T item) {
        if (item != null) {
            this.mDataList.add(position, item);
        }
        this.notifyItemInserted(position + getHeaderViewsCount());
        //必须要重新刷新一遍数据，纠正position
        this.notifyItemRangeChanged(position + getHeaderViewsCount(), mDataList.size() - position);
    }

    /**
     * 方法内已实现notify更新
     *
     * @param position
     */
    public void removeItem(int position) {
        this.mDataList.remove(position);
        this.notifyItemRemoved(position + getHeaderViewsCount());
        //必须要重新刷新一遍数据，纠正position
        this.notifyItemRangeChanged(position + getHeaderViewsCount(), mDataList.size() - position);
    }

    /**
     * 方法内已实现notify更新
     *
     * @param t
     */
    public void removeItem(T t) {
        int position = mDataList.indexOf(t);
        if (position >= 0) {
            this.mDataList.remove(t);
            this.notifyItemRemoved(position + getHeaderViewsCount());
            //必须要重新刷新一遍数据，纠正position
            this.notifyItemRangeChanged(position + getHeaderViewsCount(), mDataList.size() - position);
        }
    }

    @Override
    public int getItemCount() {
        return this.mDataList.size() + getHeaderViewsCount() + getFooterViewsCount();
    }

    public int getHeaderViewsCount() {
        return mHeaderViewContainer == null ? 0 : 1;
    }

    public int getFooterViewsCount() {
        return mFooterViewContainer == null ? 0 : 1;
    }

    //判断当前item类型
    @Override
    public int getItemViewType(int position) {
        int dataItemCount = mDataList.size();
        if (getHeaderViewsCount() != 0 && position < getHeaderViewsCount()) {
            //头部View
            return VIEW_TYPE_HEADER;
        } else if (getFooterViewsCount() != 0 && position >= (getHeaderViewsCount() + dataItemCount)) {
            //底部View
            return VIEW_TYPE_FOOTER;
        } else {
            //内容View
            return super.getItemViewType(position);
        }
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewHolder viewHolder = null;
        switch (viewType) {
            case 0:
                viewHolder = new RecyclerViewHolder(mContext, getItemView(onBindItemViewResId(), parent));
                break;
            case VIEW_TYPE_HEADER:
                viewHolder = new RecyclerViewHolder(mContext, mHeaderViewContainer);
                break;
            case VIEW_TYPE_FOOTER:
                viewHolder = new RecyclerViewHolder(mContext, mFooterViewContainer);
                break;
            default:
                break;

        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        int dataPosition = position - getHeaderViewsCount();//list中数据index
        RecyclerViewHolder recyclerViewHolder = (RecyclerViewHolder) holder;
        recyclerViewHolder.setDataPosition(dataPosition);
        switch (holder.getItemViewType()) {
            case 0:
                onBindItemViewData((RecyclerViewHolder) holder, getItem(dataPosition));
                bindItemViewClickListener(holder.itemView, recyclerViewHolder);
                break;
            case VIEW_TYPE_HEADER:
                break;
            case VIEW_TYPE_FOOTER:
                break;
            default:
                break;
        }
    }

    @Override
    protected void bindItemViewClickListener(View view, final RecyclerViewHolder finalViewHolder) {
        if (mOnItemClickListener != null) {
            finalViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int adapterPosition = finalViewHolder.getAdapterPosition() - getHeaderViewsCount();
                    if (adapterPosition < 0) {
                        return;
                    }
                    mOnItemClickListener.onItemClick(v, adapterPosition);
                }
            });
        }
        if (mOnItemLongClickListener != null) {
            finalViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int adapterPosition = finalViewHolder.getAdapterPosition() - getHeaderViewsCount();
                    if (adapterPosition < 0) {
                        return true;
                    }
                    //长按操作，如果返回false，onItemClick事件将会响应，返回true，则不会。
                    return mOnItemLongClickListener.onItemLongClick(v, adapterPosition);
                }
            });
        }
    }

    @Override
    protected void bindItemChildClickListener(View view, final RecyclerViewHolder finalViewHolder) {
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int adapterPosition = finalViewHolder.getAdapterPosition() - getHeaderViewsCount();
                if (adapterPosition < 0) {
                    return;
                }
                if (mChildClickListener != null) {
                    mChildClickListener.onItemChildClick(v, adapterPosition);
                }
            }
        });
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    if (isFullSpanType(type)) {
                        return gridManager.getSpanCount();
                    }
                    return 1;
                }
            });
        }
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        int type = holder.getItemViewType();
        if (isFullSpanType(type)) {
            setFullSpan(holder);
        }
    }

    /**
     * 是否是占满一行的类型
     *
     * @param type
     * @return
     */
    protected boolean isFullSpanType(int type) {
        return type == VIEW_TYPE_HEADER || type == VIEW_TYPE_FOOTER;
    }

    protected void setFullSpan(RecyclerView.ViewHolder holder) {
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
            params.setFullSpan(true);
        }
    }

}
